package com.njtoyo.taxi.admin.service.business.geo.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njtoyo.taxi.admin.library.Const;
import com.njtoyo.taxi.admin.library.common.util.CopyUtil;
import com.njtoyo.taxi.admin.mapper.master.entity.City;
import com.njtoyo.taxi.admin.mapper.master.mapper.CityMapper;
import com.njtoyo.taxi.admin.rest.presenter.business.geo.AllListPresenter;
import com.njtoyo.taxi.admin.rest.presenter.platfrom.AdminUserIdentityPresenter;
import com.njtoyo.taxi.admin.rest.wrapper.business.city.CityCreateWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.business.city.CityQueryWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.business.city.CityUpdateWrapper;
import com.njtoyo.taxi.admin.service.business.geo.CityService;
import com.taxi.entity.common.RestResult;
import com.njtoyo.taxi.entity.backend.AdminUser;
import com.njtoyo.taxi.entity.backend.Enum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;

@Component
@DS(Const.PRIMARY_DS)
public class CityServiceImpl implements CityService {

    @Autowired
    private CityMapper cityMapper;

    @Override
    public RestResult<IPage<City>> getList(CityQueryWrapper wrapper) {
        Page<City> page = new Page<>(wrapper.getCurrent(), wrapper.getSize());

        LambdaQueryWrapper<City> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Objects.nonNull(wrapper.getLevel()), City::getLevel, wrapper.getLevel())
                .like(Objects.nonNull(wrapper.getName()), City::getName, wrapper.getName());

        IPage<City> res = cityMapper.selectPage(page, queryWrapper);

        return RestResult.success(res);
    }

    @Override
    public RestResult create(CityCreateWrapper wrapper) {
        // 校验 shortie 和 adCode 不能重复
        if (this.checkShortieOrAdcodeExist(null, wrapper.getAdCode(), wrapper.getShortie())) {
            return RestResult.failed("地区编码或地区拼音已存在，不可重复");
        }

        City city = CopyUtil.copy(wrapper, City.class);
        cityMapper.insert(city);

        return RestResult.success();
    }

    @Override
    public RestResult<Boolean> update(Long id, CityUpdateWrapper wrapper) {
        // 校验 shortie 和 adCode 不能重复
        if (this.checkShortieOrAdcodeExist(id, wrapper.getAdCode(), wrapper.getShortie())) {
            return RestResult.failed("地区编码或地区拼音已存在，不可重复");
        }

        Boolean res = new LambdaUpdateChainWrapper<>(cityMapper)
                .eq(City::getId, id)
                .set(Objects.nonNull(wrapper.getName()), City::getName, wrapper.getName())
                .set(Objects.nonNull(wrapper.getShortie()), City::getShortie, wrapper.getShortie())
                .set(Objects.nonNull(wrapper.getCityCoordinate()), City::getCityCoordinate, wrapper.getCityCoordinate())
                .set(Objects.nonNull(wrapper.getAdCode()), City::getAdCode, wrapper.getAdCode())
                .set(Objects.nonNull(wrapper.getCityCode()), City::getCityCode, wrapper.getCityCode())
                .set(Objects.nonNull(wrapper.getLevel()), City::getLevel, wrapper.getLevel())
                .update();

        return RestResult.success();
    }

    @Override
    public RestResult<List<AllListPresenter>> getAll(AdminUser adminUser) {
        AdminUserIdentityPresenter identity = (AdminUserIdentityPresenter) adminUser.getIdentity();

        QueryWrapper<City> queryWrapper = new QueryWrapper<>();
        List<City> list;
        if (identity.getType().equals(Enum.AccountType.platform)) {
            list = cityMapper.selectList(queryWrapper);
        } else {
            list = cityMapper.getSelectByAreaIds(identity.getAreaIds());
        }
        List<AllListPresenter> res = CopyUtil.copyList(list, AllListPresenter.class);
        return RestResult.success(res);
    }

    // 校验 shortie 和 adCode 不能重复
    private Boolean checkShortieOrAdcodeExist(Long cityId, String adCode, String shortie) {
        return new LambdaQueryChainWrapper<>(cityMapper)
                .ne(Objects.nonNull(cityId), City::getId, cityId)
                .and(wrapper -> wrapper.eq(City::getAdCode, adCode).or().eq(City::getShortie, shortie))
                .count() > 0;
    }
}
